package com.example.idempotency.aspect;

import com.example.idempotency.annotation.Idempotent;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
@RequiredArgsConstructor
public class IdempotentAspect {

    private final HttpServletRequest request;
    private final StringRedisTemplate redisTemplate;

    @Around("@annotation(idempotent)")
    public Object around(ProceedingJoinPoint pjp, Idempotent idempotent) throws Throwable {
        String token = request.getHeader("Idempotency-Key");
        if (token == null || token.isEmpty()) {
            throw new RuntimeException("Missing Idempotency-Key header");
        }

        Boolean success = redisTemplate.opsForValue().setIfAbsent(token, "1", idempotent.expireSeconds(), TimeUnit.SECONDS);
        if (Boolean.FALSE.equals(success)) {
            throw new RuntimeException("Duplicate request");
        }

        return pjp.proceed();
    }
}